package com.xuecheng.media;

import com.j256.simplemagic.ContentInfo;
import com.j256.simplemagic.ContentInfoUtil;
import com.sun.xml.internal.fastinfoset.tools.FI_DOM_Or_XML_DOM_SAX_SAXEvent;
import io.minio.*;
import io.minio.errors.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.compress.utils.IOUtils;
import org.assertj.core.util.Arrays;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 冯佳鑫 又菜又爱学
 * @version 1.0
 * @DATE now()
 */
@SpringBootTest

public class chunktest {
    @Test
    void chunk() throws IOException {
        //源文件
        File sourcefile = new File("D:\\video\\aa.mp4");
        //分块文件
        File chunkfile = new File("D:\\video\\chunk");
        if (!chunkfile.exists()){
            chunkfile.mkdir();
        }
        //根据分块文件的大小，决定分成的块数
        //分块文件大小1mb
        long filesize = 1024 * 1024 * 5;
        //源文件大小
        long sourcefilesize = sourcefile.length();
        //要分成的块数
        long chunknum = (long) Math.ceil(sourcefilesize * 1.0 / filesize);
        System.out.println("分块总数" + chunknum);
        //将源文件输入到分块文件中
        byte[] bytes = new byte[1024];
        int length;
        RandomAccessFile r = new RandomAccessFile(sourcefile, "r");

        for (long i = 0; i < chunknum; i++) {
            File file = new File("D:\\video\\chunk\\" + i);
            RandomAccessFile rw = new RandomAccessFile(file, "rw");
            while ((length= r.read(bytes))!=-1){
                rw.write(bytes,0,length);
                if (file.length() >= filesize) {
                    break;
                }
            }
            rw.close();
        }
        r.close();
    }
    @Test
    //合并分块分件
    void merge() throws IOException {
        //想办法把分块文件内容全部写入到一个文件
        //1.创建一个要合并的文件
        File mergefile = new File("D:\\video\\b.mp4");
        //2.得到分块文件(数组)
        File chunkfile = new File("D:\\video\\chunk\\");
        File[] files = chunkfile.listFiles();
        //3.将分块文件排序(按文件名从小到大)
        //可以利用集合的排序
        for (int i = 0; i < files.length-1; i++) {
            for (int j = 0; j < files.length-1 - i; j++) {
                File file = new File("");
                String name1 = files[j].getName();
                int i1 = Integer.parseInt(name1);
                String name2 = files[j + 1].getName();
                int i2 = Integer.parseInt(name2);

                if (i1>i2){
                    file =  files[j];
                    files[j]   =files[j+1];
                    files[j+1]=file;
                }
            }
        }
        //将分块文件写入合并文件
        RandomAccessFile merge_r = new RandomAccessFile(mergefile,"rw");
        byte[] bytes = new byte[1024];
        int length = 0;
        for (int i = 0; i < files.length; i++) {
            //依次取出分块文件
            File file = files[i];
            RandomAccessFile chunk_wr = new RandomAccessFile(file,"rw");
            while ((length=chunk_wr.read(bytes))!= -1){
                merge_r.write(bytes,0,length);
            }
            chunk_wr.close();
        }
merge_r.close();
        //下面要检验文件是否合并成功
        String s = DigestUtils.md2Hex(new FileInputStream(mergefile));
        String a = DigestUtils.md2Hex(new FileInputStream(new File("D:\\video\\aa.mp4")));
        if (s.equals(a)){
            System.out.println("文件合并成功");
        }
    }
    MinioClient minioClient =
            MinioClient.builder()
                    .endpoint("http://192.168.101.65:9000/")
                    .credentials("minioadmin", "minioadmin").build();
    @Test
    //向minio上传文件分块
    public void  uploadchunk() throws Exception {
        File file = new File("D:\\video\\chunk");
        File[] files = file.listFiles();

        for (int i = 0; i < files.length; i++) {
            UploadObjectArgs build =
                    UploadObjectArgs.builder().bucket("testbucket").
                            filename("D:\\video\\chunk\\" + i).object("chunk/" + i)
                            .build();
            minioClient.uploadObject(build);
        }

    }
    /**
     * 合并文件到minio
     *
     */
    @Test
    public void mergefiletominio() throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        //源文件
        List<ComposeSource> composeSources = new ArrayList<>();
        for (int i = 0; i < 21; i++) {
            ComposeSource testbucket = ComposeSource.builder().bucket("testbucket").object("/chunk/" + i).build();
            composeSources.add(testbucket);
        }

                 //合并文件
        ComposeObjectArgs testbucket = ComposeObjectArgs.builder().sources(composeSources).bucket("testbucket").object("f.mp4").build();
        minioClient.composeObject(testbucket);
    }


}
